package com.iwhalecloud.bss.kite.cucc.web.controller.attr;

import com.alibaba.fastjson.JSON;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneFuncProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneFuncProdInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.dto.rule.common.DataRuleResult;
import com.iwhalecloud.bss.kite.client.dto.rule.common.DataRuleResultObj;
import com.iwhalecloud.bss.kite.client.dto.rule.common.RuleConsts;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts2;
import com.iwhalecloud.bss.kite.common.constant.SymbolConsts;
import com.iwhalecloud.bss.kite.common.dto.ContextDTO;
import com.iwhalecloud.bss.kite.common.fastdfs.ImageHandleUtil;
import com.iwhalecloud.bss.kite.common.rule.check.ICheckService;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.web.service.func.card.IProdCardAttrService;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.dto.KiteInstRelDTO;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.iwhalecloud.bss.kite.manager.inst.*;
import com.iwhalecloud.bss.kite.manager.inst.graph.IInstRelGraph;
import com.iwhalecloud.bss.kite.manager.inst.graph.impl.InstVertex;
import com.iwhalecloud.bss.kite.manager.scene.util.InstRelGraphUtils;
import com.iwhalecloud.bss.kite.manager.scene.util.InstUtils;
import com.iwhalecloud.bss.kite.manager.scene.vertex.ISubProdInstFunc;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.manager.transaction.TransactionContext;
import com.iwhalecloud.bss.kite.service.rule.RuleInitUtil;
import com.iwhalecloud.bss.kite.service.rule.RuleInstUtil;
import com.iwhalecloud.bss.kite.service.rule.RuleUtil;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.iwhalecloud.bss.kite.web.service.accept.util.AcceptEngineUtil;
import com.ztesoft.bss.base.staticdata.CoreDataOffer;
import com.ztesoft.bss.common.exception.BssException;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.rul.core.client.dto.common.RuleCommonParam;
import com.ztesoft.bss.rul.core.client.dto.offer.OfferInst;
import com.ztesoft.bss.rul.core.client.dto.offer.OfferObjInstRel;
import com.ztesoft.bss.rul.core.client.dto.prod.*;
import com.ztesoft.bss.rul.core.client.dto.rule.InputObject;
import com.ztesoft.bss.rul.core.client.dto.rule.OfferInstComp;
import com.ztesoft.bss.rul.core.client.dto.rule.ProdInstComp;
import com.ztesoft.common.logger.api.ZLogger;
import com.ztesoft.common.logger.factory.ZLoggerFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.smartcardio.ATR;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/cardRole")
@Api(tags = {"/cardRole - 卡片包组事件"})
public class ProdCardAttrController {
    @Autowired
    private IQuerySceneInstService querySceneInstService;
    @Autowired
    private IOperateSceneInstService operateSceneInstService;
    @Autowired
    private IOperateSceneFuncProdInstService operateSceneFuncProdInstService;
    @Autowired
    private IProdCardAttrService prodCardAttrService;
    @Autowired
    private IQuerySceneFuncProdInstService querySceneFuncProdInstService;

    @Autowired
    private ICheckService checkService;
    private static final ZLogger LOGGER = ZLoggerFactory.getLogger(ProdCardAttrController.class, "prodCardAttrController");
    @ApiOperation(value = "添加弹窗获取属性表格")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "funcProdId", value = "功能产品组Id", required = true),
        @ApiImplicitParam(name = "cardInstIds", value = "已添加的实例", required = false),
        @ApiImplicitParam(name = "accessProdInstId", value = "接入产品Id", required = false),
        @ApiImplicitParam(name = "isEdit", value = "实例Id", required = false)
    })
    @GetMapping(value = "/attr")
    public DataResult<Map> qryProdFuncAttr(@RequestParam String funcProdId, @RequestParam(required = false) String cardInstIds, @RequestParam(required = false) String accessProdInstId,@RequestParam(required = false) String isEdit) {
        ContextDTO context = KiteWebContext.getContext();
        String sceneInstId = context.getCurrentSceneInstId();
        //Product prodFunc = ProductCache.get(funcProdId);
        List<InstAttrDTO> attrs = prodCardAttrService.getAttrsByfuncProdId(sceneInstId,accessProdInstId,funcProdId,isEdit);
        Map<String,List> tabMap = prodCardAttrService.getInstTab(sceneInstId,funcProdId,accessProdInstId,"",isEdit,context.getCustId());
        Map res = new HashMap();
        res.put("attr",attrs);
        res.put("tab",tabMap);
        res.put("initInstId",querySceneInstService.getExtParameterValue(sceneInstId,LocalKeyConsts.TEMP_INIT_INST_ID));
        return ErrorConsts.SUCCESS.getResult(res);
    }

    @ApiOperation(value = "添加弹窗获取属性")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "funcProdId", value = "功能产品组Id", required = false),
        @ApiImplicitParam(name = "accessProdInstId", value = "接入产品Id", required = false),
        @ApiImplicitParam(name = "isEdit", value = "是否可以编辑", required = false),
        @ApiImplicitParam(name = "editInstId", value = "编辑按钮触发", required = false)
    })
    @GetMapping(value = "/attrs")
    public DataResult<Map> qryProdFuncAttrs(@RequestParam String funcProdId,@RequestParam(required = false) String accessProdInstId,@RequestParam(required = false) String isEdit,@RequestParam(required = false) String editInstId) {
        ContextDTO context = KiteWebContext.getContext();
        String sceneInstId = context.getCurrentSceneInstId();
        //Product prodFunc = ProductCache.get(funcProdId);
/*        List<KiteProdInstFunc> prodFuncInstList = querySceneInstService.listProdInstFuncsByProdId(context.getCustId(), accessProdInstId, funcProdId);
        prodFuncInstList.stream().map(pf)*/
        List<InstAttrDTO> attrs = null;
        if(KiteStringUtils.isNotEmpty(editInstId)){
            //operateSceneInstService.putExtParameter(sceneInstId,"TEMP_EDIT_INST_ID",editInstId);
            attrs = querySceneFuncProdInstService
                .listProdInstFuncAttrs(sceneInstId,context.getCustId(), editInstId, isEdit).getResultObject();
        }else{
            attrs = prodCardAttrService.getAttrsByfuncProdId(sceneInstId,accessProdInstId,funcProdId,isEdit);
        }
        Map res = new HashMap();
        res.put("attr",attrs);
        res.put("initInstId",querySceneInstService.getExtParameterValue(sceneInstId,LocalKeyConsts.TEMP_INIT_INST_ID));
        return ErrorConsts.SUCCESS.getResult(res);
    }
    @ApiOperation(value = "添加弹窗获取表格")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "funcProdId", value = "功能产品组Id", required = false),
        @ApiImplicitParam(name = "accessProdInstId", value = "接入产品Id", required = false),
        @ApiImplicitParam(name = "isEdit", value = "是否可以编辑", required = false),
        @ApiImplicitParam(name = "initInstId", value = "表单的实例id", required = false)
    })
    @GetMapping(value = "/table")
    public DataResult<Map> qryProdFuncTab(@RequestParam String funcProdId,@RequestParam(required = false) String accessProdInstId, @RequestParam(required = false) String isEdit,@RequestParam(required = false) String initInstId) {
        ContextDTO context = KiteWebContext.getContext();
        String sceneInstId = context.getCurrentSceneInstId();
        //Product prodFunc = ProductCache.get(funcProdId);
        Map<String,List> tabMap = prodCardAttrService.getInstTab(sceneInstId,funcProdId,accessProdInstId,initInstId,isEdit,context.getCustId());
        return ErrorConsts.SUCCESS.getResult(tabMap);
    }

    @KiteTransactional
    @ApiOperation(value = "添加功能产品（多选）", notes = "添加功能产品,多选")
    @ApiImplicitParams({@ApiImplicitParam(name = "accessProdInstId", value = "接入产品实例标识", required = true),
        @ApiImplicitParam(name = "funcProdId", value = "功能产品", required = true)
    })
    @PostMapping("/saveProdFuncBatch")
    public DataResult<Boolean> saveProdFuncBatch(@RequestParam String accessProdInstId, @RequestParam String funcProdId) {
        ContextDTO context = KiteWebContext.getContext();
        DataResult<List<KiteProdInstFunc>> result = new DataResult<List<KiteProdInstFunc>>();
        result.setResultObject(prodCardAttrService.saveProdFuncBatch(context.getCurrentSceneInstId(), accessProdInstId, funcProdId));
        AcceptEngineUtil.refreshScene(result);
        return ErrorConsts.SUCCESS.getResult(true);
    }
    @KiteTransactional
    @ApiOperation(value = "删除功能产品（多选）", notes = "添加功能产品,多选")
    @ApiImplicitParams({@ApiImplicitParam(name = "accessProdInstId", value = "接入产品实例标识", required = true),
        @ApiImplicitParam(name = "funcProdId", value = "功能产品", required = true)
    })
    @PostMapping("/delProdFuncBatch")
    public DataResult<Boolean> delProdFuncBatch(@RequestParam String accessProdInstId,@RequestParam String funcProdId,@RequestParam String isEdit) {
        if(KiteStringUtils.equals(isEdit,"F")){
            return new DataResult<>("1", "当前包不允许删除", false);
        }
        ContextDTO context = KiteWebContext.getContext();
        String custId = context.getCustId();
        String sceneInstId = context.getCurrentSceneInstId();
        List<KiteProdInstFunc> prodFuncInstList = querySceneInstService.listProdInstFuncsByProdId(custId, accessProdInstId, funcProdId);
        operateSceneInstService.putExtParameter(sceneInstId, KeyConsts2.LOCAL_DEL_FUNC_PROD_RULE_CHECK_FLAG, "F");
        for(KiteProdInstFunc prodInstFunc:prodFuncInstList){
            operateSceneFuncProdInstService.removeFuncProdInst(sceneInstId, accessProdInstId, prodInstFunc.getProdInstId(), KiteWebContext.getContext().getCustId(), ContextUtil.getSimpleLoginInfo().getStaffId().toString());
        }
        operateSceneInstService.removeExtParameter(sceneInstId, KeyConsts2.LOCAL_DEL_FUNC_PROD_RULE_CHECK_FLAG);
        return ErrorConsts.SUCCESS.getResult(true);
    }

    /**
     * 表格删除 只记录id 确定时真实删除
     * @param prodInstId
     * @return
     */
    @KiteTransactional
    @ApiOperation(value = "删除功能产品")
    @ApiImplicitParams(
        {
            @ApiImplicitParam(name = "prodInstId", value = "功能产品实例标识", required = true),
            @ApiImplicitParam(name = "cardInstIds", value = "已添加实例id", required = true),
            @ApiImplicitParam(name = "accessProdInstId", value = "接入产品实例id", required = true)

        })
    @DeleteMapping("delTabFunc")
    public DataResult<String> deleteProdFunc( @RequestParam String prodInstId, @RequestParam String cardInstIds,@RequestParam String accessProdInstId) {
        ContextDTO context = KiteWebContext.getContext();
        String sceneInstId = context.getCurrentSceneInstId();
        String tempId = querySceneInstService.getExtParameterValue(sceneInstId, LocalKeyConsts.TEMP_DEL_INST_ID);
        //不是已添加的实例 无需还原可以直接删除
        if(!cardInstIds.contains(prodInstId)){
            DataResult<Boolean> result = operateSceneFuncProdInstService.removeFuncProdInst(sceneInstId, accessProdInstId, prodInstId, KiteWebContext.getContext().getCustId(),
                ContextUtil.getSimpleLoginInfo().getStaffId().toString());
            AcceptEngineUtil.refreshScene(result);
        }
        //已添加的实例 点确定按钮时才真的删除
        else {
            if(KiteStringUtils.isEmpty(tempId)){
                tempId = prodInstId;
            }else {
                tempId += "," + prodInstId;
            }
            operateSceneInstService.putExtParameter(sceneInstId,LocalKeyConsts.TEMP_DEL_INST_ID,tempId);
        }
        return ErrorConsts.SUCCESS.getResult(tempId);
    }
    @KiteTransactional
    @ApiOperation(value = "取消时还原功能产品")
    @ApiImplicitParams(
        {
            @ApiImplicitParam(name = "accessProdInstId", value = "接入产品实例标识", required = true),
            @ApiImplicitParam(name = "cardInstIds", value = "已添加的实例"),
            @ApiImplicitParam(name = "funcProdId", value = "功能产品ID")
        })
    @PostMapping("/cancelTabProdFunc")
    public DataResult<Boolean> cancelTabProdFunc(  @RequestParam String accessProdInstId,@RequestParam String cardInstIds,@RequestParam String funcProdId) {
        ContextDTO context = KiteWebContext.getContext();
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        String tempInitId = querySceneInstService.getExtParameterValue(sceneInstId,LocalKeyConsts.TEMP_INIT_INST_ID);//初始实例
        // 规则埋点加特殊标识，用于跳过部分规则
        operateSceneInstService.putExtParameter(sceneInstId, KeyConsts2.LOCAL_DEL_FUNC_PROD_RULE_CHECK_FLAG, "F");
        //operateSceneInstService.putExtParameter(sceneInstId, KeyConsts2.LOCAL_DEL_FUNC_PROD_RULE_CHECK_FLAG, needCheckFlag);
        //operateSceneInstService.putExtParameter(sceneInstId, KeyConsts.KEY_DISABLE_RULE_FUNC_PROD, KeyConsts.IFTRUE_F);
        List<KiteProdInstFunc> prodFuncInstList = querySceneInstService.listProdInstFuncsByProdId(context.getCustId(), accessProdInstId, funcProdId);
        prodFuncInstList.forEach(prodFunc->{
            //若取消 删除当前窗口新增的实例
            if(KiteStringUtils.isEmpty(cardInstIds)||!cardInstIds.contains(prodFunc.getProdInstId())||KiteStringUtils.equals(tempInitId,prodFunc.getProdInstId())){
                DataResult<Boolean> result = operateSceneFuncProdInstService.removeFuncProdInst(sceneInstId, accessProdInstId, prodFunc.getProdInstId(), KiteWebContext.getContext().getCustId(),
                    ContextUtil.getSimpleLoginInfo().getStaffId().toString());
                AcceptEngineUtil.refreshScene(result);
            }
            //还原
            else{
                operateSceneFuncProdInstService
                    .restoreFuncProdInstAttr(KiteWebContext.getContextNew().getCurrentSceneInstId(), prodFunc.getProdInstId());
            }
        });
        operateSceneInstService.removeExtParameter(sceneInstId,LocalKeyConsts.TEMP_DEL_INST_ID);
        operateSceneInstService.removeExtParameter(sceneInstId,LocalKeyConsts.TEMP_INIT_INST_ID);
        operateSceneInstService.removeExtParameter(sceneInstId, KeyConsts2.LOCAL_DEL_FUNC_PROD_RULE_CHECK_FLAG);
        //operateSceneInstService.removeExtParameter(sceneInstId,TEMP_DEL_INST_ID);
        //operateSceneInstService.putExtParameter(sceneInstId, KeyConsts.KEY_DISABLE_RULE_FUNC_PROD, KeyConsts.IFTRUE_T);
        return ErrorConsts.SUCCESS.getResult(true);
    }
    @KiteTransactional
    @ApiOperation(value = "确定时删除标记功能产品")
    @ApiImplicitParams(
        {
            @ApiImplicitParam(name = "accessProdInstId", value = "接入产品实例标识", required = true)
        })
    @PostMapping("/yesTabProdFunc")
    public DataResult<Boolean> yesTabProdFunc( @RequestParam String accessProdInstId){
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        String tempInitId = querySceneInstService.getExtParameterValue(sceneInstId,LocalKeyConsts.TEMP_INIT_INST_ID);//初始实例
        String tempId = querySceneInstService.getExtParameterValue(sceneInstId,LocalKeyConsts.TEMP_DEL_INST_ID);
        operateSceneInstService.putExtParameter(sceneInstId, KeyConsts2.LOCAL_DEL_FUNC_PROD_RULE_CHECK_FLAG, "F");
        if(KiteStringUtils.isNotEmpty(tempId)){
            String [] tempIds = tempId.split(",");
            for (String delId : tempIds){
                DataResult<Boolean> result = operateSceneFuncProdInstService.removeFuncProdInst(sceneInstId, accessProdInstId, delId, KiteWebContext.getContext().getCustId(),
                    ContextUtil.getSimpleLoginInfo().getStaffId().toString());
                AcceptEngineUtil.refreshScene(result);
            }
        }
        if(KiteStringUtils.isNotEmpty(tempInitId)){
            DataResult<Boolean> result = operateSceneFuncProdInstService.removeFuncProdInst(sceneInstId, accessProdInstId, tempInitId, KiteWebContext.getContext().getCustId(),
                ContextUtil.getSimpleLoginInfo().getStaffId().toString());
            AcceptEngineUtil.refreshScene(result);
        }
        operateSceneInstService.removeExtParameter(sceneInstId, KeyConsts2.LOCAL_DEL_FUNC_PROD_RULE_CHECK_FLAG);
        operateSceneInstService.removeExtParameter(sceneInstId,LocalKeyConsts.TEMP_DEL_INST_ID);
        operateSceneInstService.removeExtParameter(sceneInstId,LocalKeyConsts.TEMP_INIT_INST_ID);
        return ErrorConsts.SUCCESS.getResult(true);
    }
    /**
     * 当功能产品点击确定是触发该规则
     * @return
     */
    @ApiOperation(value="新增功能产品点击确定是触发校验规则",notes = "新增功能产品点击确定是触发校验规则")
    @PostMapping(value = "/checkAddFuncProductCommit")
    public Object checkAddFuncProductCommit(@RequestParam(required = false)  String accessProdInstId,
                                            @RequestParam(required = false) String funcProdId
        ,@RequestParam(required = false) String fieldName,@RequestParam(required = false) String attrValue,@RequestParam(required = false) String addFlag){
        //保留规则调用 添加时暂时不调用规则
        if(KiteStringUtils.equals(addFlag,"T")){
            DataRuleResult result = new DataRuleResult();
            DataRuleResultObj ruleResultObj = new DataRuleResultObj();
            result.setResultCode(RuleConsts.RULE_RESPONSE_SUCCESS);
            result.setResultObject(ruleResultObj);
            ruleResultObj.setCheckFlag(true);
            return result;
        }
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        String custId = KiteWebContext.getContext().getCustId();
        String staffId = String.valueOf(ContextUtil.getUserId());
        String tempInitId = querySceneInstService.getExtParameterValue(sceneInstId,LocalKeyConsts.TEMP_INIT_INST_ID);//初始实例
        String tempId = querySceneInstService.getExtParameterValue(sceneInstId,LocalKeyConsts.TEMP_DEL_INST_ID);
        String ruleTempId = "";
        ruleTempId += Optional.ofNullable(tempInitId).orElse("");
        ruleTempId += !KiteStringUtils.isAnyEmpty(ruleTempId,tempId)?SymbolConsts.COMMA:"";
        ruleTempId += Optional.ofNullable(tempId).orElse("");
        List<KiteProdInstFunc> prodFuncInstList = querySceneInstService.listProdInstFuncsByProdId(custId, accessProdInstId, funcProdId);
        prodFuncInstList.removeIf(pd->KiteStringUtils.equalsAny(pd.getProdInstId(),tempId,tempInitId)||(KiteStringUtils.isNotEmpty(tempId)&&tempId.contains(pd.getProdInstId())));
        List<String> prodList = new ArrayList<>();
        if(KiteListUtils.isNotEmpty(prodFuncInstList)){
            prodList = prodFuncInstList.stream().map(KiteProdInstFunc::getProdInstId).collect(Collectors.toList());
        }
        RuleCommonParam ruleCommonParam = RuleUtil.getRuleCommonParam(sceneInstId , custId);
        Map<String, Object> params = ruleCommonParam.getParams();
        if(Objects.isNull(params)){
            params = new HashMap();
            ruleCommonParam.setParams(params);
        }
        params.put("tempInstId",ruleTempId);
        params.put("accessProdInstId",accessProdInstId);
        return checkService.checkAddFuncProductCommit(accessProdInstId,prodList,sceneInstId,custId,
            staffId,ruleCommonParam,fieldName,attrValue);
    }
}
